﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace tactics.MapBuilders
{
    class CavesBuilder : IMapBuilder
    {
        int width;
        int height;
        float scale;

        TileInfo[] mapInfo;

        #region Properties

        public int Width
        {
            get { return width; }
        }

        public int Height
        {
            get { return height; }
        }

        public float Scale
        {
            get { return scale; }
        }

        public string TileXMLFile
        {
            get { return "Content/TileSets/caves.xml"; }
        }

        public TileInfo[] MapInfo
        {
            get { return mapInfo; }
        }

        public bool SmoothTerrain
        {
            get { return false; }
        }

        #endregion

        public CavesBuilder(int widthIn, int heightIn, float scaleIn)
        {
            width = widthIn;
            height = heightIn;
            scale = scaleIn;
        }

        public HeightMap GenerateMap(TileSet tileSet)
        {
            HeightMap heightMap = new HeightMap(width, height, scale, 0f, 0f, 0f, 0);

            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                {
                    heightMap.SetHeight(x, y, 2.0f);
                }
            }

            GenerateTiles(tileSet, heightMap);
            return heightMap;
        }

        private void GenerateTiles(TileSet tileSet, HeightMap heightMap)
        {
            Random r = new Random(heightMap.Seed);

            mapInfo = new TileInfo[width * height];

            int idx = 0;
            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                {
                    string type = "Void";
                    mapInfo[idx] = tileSet.GetTileInfo(type);
                    ++idx;
                }
            }

            int numRooms = 100;
            for (int i = 0; i < numRooms; ++i)
            {
                int x = r.Next(1, width - 1);
                int y = r.Next(1, height - 1);

                int w = r.Next(5, 10);
                int h = r.Next(5, 10);

                if (x + w < width && y + h < height)
                    CreateRoom(x, y, w, h, heightMap, tileSet);
                else
                    ++numRooms;
            }

            for (int y = 0; y < height; ++y)
                for (int x = 0; x < height; ++x)
                {
                    float currHeight = heightMap.GetHeight(x, y);
                    if (currHeight == 0.0f && mapInfo[heightMap.AtCoord(x, y)] == tileSet.GetTileInfo("Void"))
                    {
                        bool flat = true;

                        if (x != width - 1 && y != height - 1)
                            flat =  currHeight == heightMap.GetHeight(x + 1, y) &&
                                    currHeight == heightMap.GetHeight(x, y + 1) &&
                                    currHeight == heightMap.GetHeight(x + 1, y + 1);

                        if (flat)
                            mapInfo[heightMap.AtCoord(x, y)] = tileSet.GetTileInfo("Sand");
                    }
                }
        }

        private void CreateRoom(int x, int y, int w, int h, HeightMap heightMap, TileSet tileSet)
        {
            for (int yy = 0; yy < h; ++yy)
            {
                for (int xx = 0; xx < w; ++xx)
                {
                    heightMap.SetHeight(x + xx, y + yy, 0.0f);
                    if (xx < w - 1 && yy < h - 1)
                        mapInfo[heightMap.AtCoord(x + xx, y + yy)] = tileSet.GetTileInfo("CaveFloor");
                }
            }
        }
    }
}